package com.dongdongshop.service.imp;

import com.alibaba.druid.sql.visitor.functions.Now;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dongdongshop.mapper.TbSeckillGoodsMapper;
import com.dongdongshop.mapper.TbSeckillOrderMapper;
import com.dongdongshop.pojo.TbSeckillGoods;
import com.dongdongshop.pojo.TbSeckillGoodsExample;
import com.dongdongshop.pojo.TbSeckillOrder;
import com.dongdongshop.service.SeckillService;
import com.dongdongshop.util.IdWorker;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@org.springframework.stereotype.Service
public class SeckillServiceImp implements SeckillService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TbSeckillGoodsMapper tbSeckillGoodsMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public List<TbSeckillGoods> selectSeckill() {
        // 将String的value值序列化 (转化为我们能看懂的)
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //先查缓存,缓存里面没有,在咨询数据库
        List<TbSeckillGoods> goodsList = (List<TbSeckillGoods>) redisTemplate.boundHashOps("goodsList").values();
        //缓存中没有
        if (goodsList == null || goodsList.isEmpty()) {
            TbSeckillGoodsExample ts = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = ts.createCriteria();
            criteria.andStatusEqualTo("1");
            Date date = new Date();
            criteria.andStartTimeLessThanOrEqualTo(date);
            criteria.andEndTimeGreaterThanOrEqualTo(date);
            criteria.andStockCountGreaterThan(0);
            goodsList = tbSeckillGoodsMapper.selectByExample(ts);
            //存入缓存
            goodsList.stream().forEach(goods -> {
                redisTemplate.boundHashOps("goodsList").put(goods.getId(), goods);
                //单独把库存抽取出来,做成预减库存
                redisTemplate.boundValueOps(goods.getId()).set(goods.getStockCount().toString());
            });
//            for (TbSeckillGoods seckillGoods:goodsList) {
//                redisTemplate.boundHashOps("goodsList").put(seckillGoods.getId(), seckillGoods);
//            }
        }
        return goodsList;
    }

    @Override
    public TbSeckillGoods findGoodsById(Long id) {
        return (TbSeckillGoods) redisTemplate.boundHashOps("goodsList").get(id);
    }

    @Override
    public void createOrder(Long id, String username) {
//        //1.从缓存中查出商品
//        TbSeckillGoods goods = (TbSeckillGoods) redisTemplate.boundHashOps("goodsList").get(id);
//        //2.判断商品库存是否为零,商品是否为null
//        if (goods == null || goods.getStockCount() <= 0) {
//            throw new RuntimeException("商品已经卖光了");
//        }
        String stockCount = (String)redisTemplate.boundValueOps(id).get();
        if (stockCount == null && Long.parseLong(stockCount) <= 0){
            throw new RuntimeException("商品已经卖光了");
        }
        //3.减库存
//        goods.setStockCount(goods.getStockCount() - 1);
        //将库存减一并且返回减一之后的值,整个操作是原子性的;
        Long decrement = redisTemplate.boundValueOps(id).decrement();
        //减过库存的商品从新放入缓存
//        redisTemplate.boundHashOps("goodsList").put(id, goods);
        if (decrement <= 0) {//说明已经是最后一件
            TbSeckillGoods goods = (TbSeckillGoods) redisTemplate.boundHashOps("goodsList").get(id);
            goods.setStockCount(0);
            tbSeckillGoodsMapper.updateByPrimaryKeySelective(goods);
            redisTemplate.boundHashOps("goodsList").delete(id);
            redisTemplate.delete(id);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("id",id);
        map.put("username",username);
        rocketMQTemplate.convertAndSend("yangyangyang",map);
        //4.创建订单
//        TbSeckillOrder seckillOrder = new TbSeckillOrder();
//        seckillOrder.setId(idWorker.nextId());
//        seckillOrder.setUserId(username);
//        seckillOrder.setStatus("1");//待支付
//        seckillOrder.setSellerId(goods.getSellerId());
//        seckillOrder.setSeckillId(goods.getId());
//        seckillOrder.setMoney(goods.getCostPrice());
//        seckillOrder.setCreateTime(new Date());
//        tbSeckillOrderMapper.insertSelective(seckillOrder);

    }

    @Override
    public Long getOrderId(String username) {
        return (Long) redisTemplate.boundHashOps("order1").get(username);
    }
}
